package com.cdp.system.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cdp.common.core.domain.entity.ChartConfigsUser;
import com.cdp.common.core.domain.entity.ChartFiles;
import com.cdp.common.core.domain.entity.ChartRecord;
import com.cdp.common.utils.SecurityUtils;
import com.cdp.system.dto.ChartConfigUserDTO;
import com.cdp.system.dto.ChartFileTreeDTO;
import com.cdp.system.dto.ChartFolderTreeDTO;
import com.cdp.system.dto.ChartRecordDTO;
import com.cdp.system.mapper.ChartConfigsUserMapper;
import com.cdp.system.mapper.ChartFilesMapper;
import com.cdp.system.mapper.ChartRecordMapper;
import com.cdp.system.service.IChartFilesService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 文件夹业务层
 */
@Service
public class ChartFilesServiceImpl extends ServiceImpl<ChartFilesMapper, ChartFiles> implements IChartFilesService {

    @Autowired
    private ChartFilesMapper chartFilesMapper;

    @Autowired
    private ChartConfigsUserMapper chartConfigsUserMapper;


    @Autowired
    private ChartRecordMapper chartRecordMapper;

    @Override
    public List<ChartFileTreeDTO> getFolderFileTree(String name) {
        Long userId = SecurityUtils.getUserId();
        List<ChartFiles> allFolders = chartFilesMapper.selectFilesByName(name, userId);
        List<ChartConfigsUser> allFiles = chartConfigsUserMapper.selectConfigsByName(name, userId);
        if (name != null) {
            List<ChartFileTreeDTO> matchedFolders = allFolders.stream()
                    .filter(folder -> folder.getFileName() != null && folder.getFileName().contains(name))
                    .map(this::convertToDTO)
                    .collect(Collectors.toList());


            List<ChartConfigUserDTO> matchedFiles = allFiles.stream()
                    .filter(file -> file.getChartName() != null && file.getChartName().contains(name))
                    .map(this::convertFileToDTO)
                    .collect(Collectors.toList());


            if (!matchedFolders.isEmpty() || !matchedFiles.isEmpty()) {
                ChartFileTreeDTO matchedNode = new ChartFileTreeDTO();
                matchedNode.setFileName("我的生成");
                matchedNode.setChildren(matchedFolders);
                matchedNode.setFiles(matchedFiles);
                return Arrays.asList(matchedNode);
            }
        }


        List<ChartFileTreeDTO> folderDTOList = allFolders.stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList());
        List<ChartConfigUserDTO> fileDTOList = allFiles.stream()
                .map(this::convertFileToDTO)
                .collect(Collectors.toList());

        Map<Long, List<ChartConfigUserDTO>> filesByFolderId = fileDTOList.stream()
                .filter(file -> file.getFileId() != null)
                .collect(Collectors.groupingBy(ChartConfigUserDTO::getFileId));
        List<ChartConfigUserDTO> rootFiles = fileDTOList.stream()
                .filter(file -> file.getFileId() == null)
                .collect(Collectors.toList());

        List<ChartFileTreeDTO> rootFolders = buildTree(folderDTOList, filesByFolderId, null);

        ChartFileTreeDTO rootNode = new ChartFileTreeDTO();
        rootNode.setFileName("我的生成");
        rootNode.setFiles(rootFiles);
        rootNode.setChildren(rootFolders);

        return Arrays.asList(rootNode);
    }



    // 递归方法构建树状结构
    private List<ChartFileTreeDTO> buildTree(List<ChartFileTreeDTO> folderList,
                                             Map<Long, List<ChartConfigUserDTO>> filesByFolderId,
                                             Long parentId) {
        return folderList.stream()
                // 如果 parentId 是 null 则选择根层级，或者 parentId 相等的情况下才会递归添加到子层级
                .filter(folder -> (parentId == null && folder.getParentId() == null) ||
                        (parentId != null && parentId.equals(folder.getParentId())))
                .map(folder -> {
                    // 设置文件列表，file_id 为空的文件也会在根层级
                    if (parentId == null) {
                        List<ChartConfigUserDTO> rootFiles = filesByFolderId.get(null);
                        if (rootFiles != null) {
                            folder.setFiles(rootFiles);
                        }
                    }
                    folder.setFiles(filesByFolderId.get(folder.getFileId()));

                    // 递归查找子文件夹
                    folder.setChildren(buildTree(folderList, filesByFolderId, folder.getFileId()));
                    return folder;
                })
                .collect(Collectors.toList());
    }

    // 将 ChartFiles 转换为 ChartFileTreeDTO
    private ChartFileTreeDTO convertToDTO(ChartFiles chartFile) {
        ChartFileTreeDTO dto = new ChartFileTreeDTO();
        dto.setFileId(chartFile.getFileId());
        dto.setFileName(chartFile.getFileName());
        dto.setParentId(chartFile.getParentId());
        return dto;
    }

    // 将 ChartConfigsUser 转换为 ChartConfigUserDTO
    private ChartConfigUserDTO convertFileToDTO(ChartConfigsUser chartConfigUser) {
        ChartConfigUserDTO dto = new ChartConfigUserDTO();
        dto.setId(chartConfigUser.getId());
        dto.setChartName(chartConfigUser.getChartName());
        dto.setFileId(chartConfigUser.getFileId());
        dto.setChartValue(chartConfigUser.getChartValue());
        dto.setImageUrl(chartConfigUser.getImageUrl()); // 设置 imageUrl
        return dto;
    }






/*
    @Override
    public List<ChartFolderTreeDTO> getUpdatedFolderFileTree(String name) {
        Long userId = SecurityUtils.getUserId();

        // 查询 chart_files 和 chart_record 表
        List<ChartFiles> allFolders = chartFilesMapper.selectFilesByName(name, userId);
        List<ChartRecord> allRecords = chartRecordMapper.selectRecordsByName(name, userId);

        if (name != null) {
            // 筛选匹配的文件夹
            List<ChartFolderTreeDTO> matchedFolders = allFolders.stream()
                    .filter(folder -> folder.getFileName() != null && folder.getFileName().contains(name))
                    .map(this::convertToUpdatedFolderTreeDTO)
                    .collect(Collectors.toList());

            // 筛选匹配的图表记录
            List<ChartRecordDTO> matchedRecords = allRecords.stream()
                    .filter(record -> record.getUserChartName() != null && record.getUserChartName().contains(name))
                    .map(this::convertToUpdatedRecordDTO)
                    .collect(Collectors.toList());

            if (!matchedFolders.isEmpty() || !matchedRecords.isEmpty()) {
                ChartFolderTreeDTO matchedNode = new ChartFolderTreeDTO();
                matchedNode.setFileName("我的生成");
                matchedNode.setChildren(matchedFolders);
                matchedNode.setFiles(matchedRecords);
                return Arrays.asList(matchedNode);
            }
        }

        // 将文件夹和记录都转为 DTO
        List<ChartFolderTreeDTO> folderDTOList = allFolders.stream()
                .map(this::convertToUpdatedFolderTreeDTO)
                .collect(Collectors.toList());
        List<ChartRecordDTO> recordDTOList = allRecords.stream()
                .map(this::convertToUpdatedRecordDTO)
                .collect(Collectors.toList());

        // 根据文件夹 ID 分组图表记录
        Map<String, List<ChartRecordDTO>> recordsByFolderId = recordDTOList.stream()
                .filter(record -> record.getFileId() != null)
                .collect(Collectors.groupingBy(ChartRecordDTO::getFileId));  // 这里使用 String 类型

        // 获取根目录下的图表记录
        List<ChartRecordDTO> rootRecords = recordDTOList.stream()
                .filter(record -> record.getFileId() == null)
                .collect(Collectors.toList());

        // 构建文件夹树
        List<ChartFolderTreeDTO> rootFolders = buildUpdatedTree(folderDTOList, recordsByFolderId, null);

        // 构建根节点，包含文件夹和图表记录
        ChartFolderTreeDTO rootNode = new ChartFolderTreeDTO();
        rootNode.setFileName("我的生成");
        rootNode.setFiles(rootRecords);
        rootNode.setChildren(rootFolders);

        return Arrays.asList(rootNode);
    }

*/

    @Override
    public List<ChartFolderTreeDTO> getUpdatedFolderFileTree(String name) {
        Long userId = SecurityUtils.getUserId();

        // 查询 chart_files 和 chart_record 表
        List<ChartFiles> allFolders = chartFilesMapper.selectFilesByName(name, userId);
        List<ChartRecord> allRecords = chartRecordMapper.selectRecordsByName(name, userId);

        if (name != null) {
            // 筛选匹配的文件夹
            List<ChartFolderTreeDTO> matchedFolders = allFolders.stream()
                    .filter(folder -> folder.getFileName() != null && folder.getFileName().contains(name))
                    .map(this::convertToUpdatedFolderTreeDTO)
                    .collect(Collectors.toList());

            // 筛选匹配的图表记录
            List<ChartRecordDTO> matchedRecords = allRecords.stream()
                    .filter(record -> record.getUserChartName() != null && record.getUserChartName().contains(name))
                    .map(this::convertToUpdatedRecordDTO)
                    .collect(Collectors.toList());

            if (!matchedFolders.isEmpty() || !matchedRecords.isEmpty()) {
                ChartFolderTreeDTO matchedNode = new ChartFolderTreeDTO();
                matchedNode.setFileName("我的生成");
                matchedNode.setChildren(matchedFolders);
                matchedNode.setFiles(matchedRecords);
                return Arrays.asList(matchedNode);
            }
        }

        // 将所有文件夹和记录转换为 DTO
        List<ChartFolderTreeDTO> folderDTOList = allFolders.stream()
                .map(this::convertToUpdatedFolderTreeDTO)
                .collect(Collectors.toList());
        List<ChartRecordDTO> recordDTOList = allRecords.stream()
                .map(this::convertToUpdatedRecordDTO)
                .collect(Collectors.toList());

        // 按 fileId 分组图表记录（包括 fileId 为 NULL 的记录）
        Map<String, List<ChartRecordDTO>> recordsByFolderId = recordDTOList.stream()
                .filter(record -> record.getFileId() != null)
                .collect(Collectors.groupingBy(ChartRecordDTO::getFileId));

        // 获取 root 级别的记录（fileId 为 NULL 的记录）
        List<ChartRecordDTO> rootRecords = recordDTOList.stream()
                .filter(record -> record.getFileId() == null)
                .collect(Collectors.toList());

        // 构建文件夹树结构
        List<ChartFolderTreeDTO> rootFolders = buildUpdatedTree(folderDTOList, recordsByFolderId, null);

        // 创建根节点，包含文件夹和图表记录
        ChartFolderTreeDTO rootNode = new ChartFolderTreeDTO();
        rootNode.setFileName("我的生成");
        rootNode.setFiles(rootRecords);  // 这里添加了根目录下的文件
        rootNode.setChildren(rootFolders);

        return Arrays.asList(rootNode);
    }


    private ChartFolderTreeDTO convertToUpdatedFolderTreeDTO(ChartFiles chartFile) {
        ChartFolderTreeDTO dto = new ChartFolderTreeDTO();
        // 将 fileId 从 Long 转换为 String
        dto.setFileId(String.valueOf(chartFile.getFileId()));
        dto.setFileName(chartFile.getFileName());
        dto.setParentId(chartFile.getParentId());
        return dto;
    }


//    private ChartRecordDTO convertToUpdatedRecordDTO(ChartRecord chartRecord) {
//        ChartRecordDTO dto = new ChartRecordDTO();
//        dto.setId(chartRecord.getId());
//        //dto.setUserChartName(chartRecord.getUserChartName());
//        dto.setFileName(chartRecord.getUserChartName());
//        // 将 fileId 从 Long 转换为 String
//        dto.setFileId(String.valueOf(chartRecord.getFileId()));
//        dto.setIds(chartRecord.getUserChartOption());
//        dto.setSource(chartRecord.getSource());
//       // dto.setStatus(chartRecord.getStatus());
//       // dto.setCreateTime(chartRecord.getCreateTime());
//       // dto.setUpdateTime(chartRecord.getUpdateTime());
//       // dto.setRecordId(chartRecord.getRecordId());
//        return dto;
//    }

    private ChartRecordDTO convertToUpdatedRecordDTO(ChartRecord chartRecord) {
        ChartRecordDTO dto = new ChartRecordDTO();
        dto.setId(chartRecord.getId());
        dto.setFileName(chartRecord.getUserChartName());
        dto.setFileId(chartRecord.getFileId() != null ? String.valueOf(chartRecord.getFileId()) : null);  // 确保为空的 file_id 被正确处理
        dto.setIds(chartRecord.getUserChartOption());
        dto.setSource(chartRecord.getSource());
        return dto;
    }



    private List<ChartFolderTreeDTO> buildUpdatedTree(List<ChartFolderTreeDTO> folderList,
                                                      Map<String, List<ChartRecordDTO>> filesByFolderId,
                                                      String parentId) {
        return folderList.stream()
                // 如果 parentId 是 null，则选择根层级，或者 parentId 相等的情况下才会递归添加到子层级
                .filter(folder -> (parentId == null && folder.getParentId() == null) ||
                        (parentId != null && parentId.equals(String.valueOf(folder.getParentId()))))
                .map(folder -> {
                    // 如果 parentId 为 null，表示是根节点
                    if (parentId == null) {
                        List<ChartRecordDTO> rootFiles = filesByFolderId.get(null);
                        if (rootFiles != null) {
                            folder.setFiles(rootFiles);
                        }
                    }
                    // 为当前文件夹设置对应的图表记录
                    folder.setFiles(filesByFolderId.get(folder.getFileId()));  // 使用 String 类型的 fileId

                    // 递归查找子文件夹
                    folder.setChildren(buildUpdatedTree(folderList, filesByFolderId, folder.getFileId()));
                    return folder;
                })
                .collect(Collectors.toList());
    }


}
